package com.arvin.faceDetect.service

import android.annotation.SuppressLint
import android.app.Service
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.graphics.PixelFormat
import android.os.Build
import android.os.IBinder
import android.view.Gravity
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Button
import android.widget.ScrollView
import android.widget.Spinner
import android.widget.TextView
import android.widget.Toast
import com.arvin.faceDetect.R
import java.io.BufferedReader
import java.io.File
import java.io.FileReader
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import kotlin.math.abs

class FloatingLogService : Service() {
    private var windowManager: WindowManager? = null
    private var floatingButton: View? = null
    private var logWindow: View? = null
    private var isLogWindowShowing = false
    private var initialX: Int = 0
    private var initialY: Int = 0
    private var initialTouchX: Float = 0f
    private var initialTouchY: Float = 0f
    private var logView: View? = null
    private var lastX: Int = 0
    private var lastY: Int = 0
    private var logContent = StringBuilder()
    private var currentFilter = "全部"

    companion object {
        private const val MAX_LOG_LINES = 1000
        private const val TAG = "FloatingLogService"
    }

    override fun onBind(intent: Intent): IBinder? = null

    override fun onCreate() {
        super.onCreate()
        createFloatingButton()
        createLogWindow()
        startLogcatReader()
    }

    private fun createFloatingButton() {
        windowManager = getSystemService(WINDOW_SERVICE) as WindowManager

        floatingButton = LayoutInflater.from(this)
            .inflate(R.layout.layout_floating_button, null)

        val params = WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
            else
                WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT
        )

        params.gravity = Gravity.TOP or Gravity.START
        params.x = 0
        params.y = 100

        floatingButton?.setOnTouchListener { view, event ->
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    initialX = params.x
                    initialY = params.y
                    initialTouchX = event.rawX
                    initialTouchY = event.rawY
                    true
                }
                MotionEvent.ACTION_MOVE -> {
                    val dx = event.rawX - initialTouchX
                    val dy = event.rawY - initialTouchY
                    params.x = (initialX + dx).toInt()
                    params.y = (initialY + dy).toInt()
                    windowManager?.updateViewLayout(view, params)
                    true
                }
                MotionEvent.ACTION_UP -> {
                    val dx = abs(event.rawX - initialTouchX)
                    val dy = abs(event.rawY - initialTouchY)
                    if (dx < 5 && dy < 5) {
                        if (isLogWindowShowing) {
                            hideLogWindow()
                        } else {
                            showLogWindow()
                        }
                    }
                    true
                }
                else -> false
            }
        }

        windowManager?.addView(floatingButton, params)
    }

    private fun createLogWindow() {
        windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
        val inflater = getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater
        logView = inflater.inflate(R.layout.layout_log_window, null)

        // 设置窗口参数
        val params = WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT
        )

        // 初始化过滤器下拉框
        val spinner = logView?.findViewById<Spinner>(R.id.spinnerFilter)
        val filterItems =
            arrayOf(
                "全部",
                "FaceSDK",
                "FaceAutoCollect",
                "FaceDetectionFragment",
                "FaceOverlayView"
            )
        val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, filterItems)
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        spinner?.adapter = adapter

        spinner?.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(
                parent: AdapterView<*>?,
                view: View?,
                position: Int,
                id: Long
            ) {
                currentFilter = filterItems[position]
                updateLogContent()
            }

            override fun onNothingSelected(parent: AdapterView<*>?) {}
        }

        // 设置按钮点击事件
        logView?.findViewById<Button>(R.id.btnCopy)?.setOnClickListener {
            val clipboard = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
            val clip = ClipData.newPlainText("log", logContent.toString())
            clipboard.setPrimaryClip(clip)
            Toast.makeText(this, "日志已复制到剪贴板", Toast.LENGTH_SHORT).show()
        }

        logView?.findViewById<Button>(R.id.btnClear)?.setOnClickListener {
            logContent.clear()
            updateLogContent()
        }

        logView?.findViewById<Button>(R.id.btnClose)?.setOnClickListener {
            stopSelf()
        }

        // 设置拖动事件
        logView?.setOnTouchListener(object : View.OnTouchListener {
            @SuppressLint("ClickableViewAccessibility")
            override fun onTouch(v: View?, event: MotionEvent?): Boolean {
                when (event?.action) {
                    MotionEvent.ACTION_DOWN -> {
                        initialX = params.x
                        initialY = params.y
                        initialTouchX = event.rawX
                        initialTouchY = event.rawY
                        return true
                    }

                    MotionEvent.ACTION_MOVE -> {
                        params.x = initialX + (event.rawX - initialTouchX).toInt()
                        params.y = initialY + (event.rawY - initialTouchY).toInt()
                        windowManager?.updateViewLayout(logView, params)
                        return true
                    }
                }
                return false
            }
        })

        windowManager?.addView(logView, params)
    }

    private fun startLogcatReader() {
        Thread {
            try {
                val process = Runtime.getRuntime().exec("logcat")
                val bufferedReader = process.inputStream.bufferedReader()

                while (true) {
                    val line = bufferedReader.readLine() ?: break
                    if (shouldShowLog(line)) {
                        addLogLine(line)
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }.start()
    }

    private fun shouldShowLog(line: String): Boolean {
        return when (currentFilter) {
            "全部" -> true
            else -> line.contains(currentFilter)
        }
    }

    private fun addLogLine(line: String) {
        logContent.append(line).append("\n")

        // 限制日志行数
        val lines = logContent.toString().split("\n")
        if (lines.size > MAX_LOG_LINES) {
            logContent.clear()
            logContent.append(lines.takeLast(MAX_LOG_LINES).joinToString("\n"))
        }

        updateLogContent()
    }

    private fun updateLogContent() {
        val textView = logView?.findViewById<TextView>(R.id.tvLogContent)
        val scrollView = logView?.findViewById<ScrollView>(R.id.scrollView)

        textView?.post {
            textView.text = logContent.toString()
            scrollView?.post {
                scrollView.fullScroll(ScrollView.FOCUS_DOWN)
            }
        }
    }

    private fun showLogWindow() {
        if (logWindow == null) {
            logWindow = LayoutInflater.from(this).inflate(R.layout.layout_log_window, null)
            
            val params = WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
                    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
                else
                    WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
                PixelFormat.TRANSLUCENT
            )

            params.gravity = Gravity.TOP or Gravity.START
            params.x = 0
            params.y = 100
            
            // 设置复制按钮
            logWindow?.findViewById<View>(R.id.btnCopy)?.setOnClickListener {
                copyLogToClipboard()
            }
            
            // 设置关闭按钮
            logWindow?.findViewById<View>(R.id.btnClose)?.setOnClickListener {
                hideLogWindow()
            }
            
            // 设置清除按钮
            logWindow?.findViewById<View>(R.id.btnClear)?.setOnClickListener {
                clearLogs()
                updateLogContent()
            }

            // 添加拖动功能
            var initialX = 0
            var initialY = 0
            var initialTouchX = 0f
            var initialTouchY = 0f

            logWindow?.setOnTouchListener { view, event ->
                when (event.action) {
                    MotionEvent.ACTION_DOWN -> {
                        initialX = params.x
                        initialY = params.y
                        initialTouchX = event.rawX
                        initialTouchY = event.rawY
                        true
                    }

                    MotionEvent.ACTION_MOVE -> {
                        val dx = (event.rawX - initialTouchX).toInt()
                        val dy = (event.rawY - initialTouchY).toInt()
                        params.x = initialX + dx
                        params.y = initialY + dy
                        windowManager?.updateViewLayout(view, params)
                        true
                    }

                    else -> false
                }
            }
            
            windowManager?.addView(logWindow, params)
        }
        
        updateLogContent()
        isLogWindowShowing = true
    }

    private fun hideLogWindow() {
        logWindow?.let {
            windowManager?.removeView(it)
            logWindow = null
            isLogWindowShowing = false
        }
    }

    private fun readCrashLogs(): String {
        val crashLogDir = File(getExternalFilesDir(null), "crash_logs")
        if (!crashLogDir.exists()) return ""

        val logContent = StringBuilder()
        crashLogDir.listFiles()?.sortedByDescending { it.lastModified() }?.take(5)?.forEach { file ->
            try {
                BufferedReader(FileReader(file)).use { reader ->
                    logContent.append("时间：${SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
                        .format(Date(file.lastModified()))}\n")
                    reader.forEachLine { line ->
                        logContent.append(line).append("\n")
                    }
                    logContent.append("\n")
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
        return logContent.toString()
    }

    private fun clearLogs() {
        try {
            // 清除系统日志
            Runtime.getRuntime().exec("logcat -c")
            
            // 清除崩溃日志
            val crashLogDir = File(getExternalFilesDir(null), "crash_logs")
            if (crashLogDir.exists()) {
                crashLogDir.listFiles()?.forEach { it.delete() }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun copyLogToClipboard() {
        val logContent = logWindow?.findViewById<TextView>(R.id.tvLogContent)?.text?.toString() ?: return
        
        // 将日志内容按行分割
        val lines = logContent.split("\n")
        
        // 获取最新的50行
        val lastLines = if (lines.size > 50) {
            // 找到最后一个标题的位置
            val lastTitleIndex = lines.indices.reversed().find { 
                lines[it].startsWith("【") && lines[it].endsWith("】")
            } ?: -1
            
            // 如果最后50行中包含了标题的一部分，就从标题开始复制
            if (lastTitleIndex >= 0 && lastTitleIndex > lines.size - 50) {
                lines.subList(lastTitleIndex, lines.size)
            } else {
                lines.subList(lines.size - 50, lines.size)
            }
        } else {
            lines
        }
        
        // 组合最终要复制的内容
        val copyContent = StringBuilder().apply {
            if (lastLines.size < lines.size) {
                appendLine("...(省略前面${lines.size - lastLines.size}行)...")
                appendLine()
            }
            append(lastLines.joinToString("\n"))
        }.toString()
        
        val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
        val clip = ClipData.newPlainText("错误日志", copyContent)
        clipboard.setPrimaryClip(clip)
        
        Toast.makeText(this, "已复制最新的${lastLines.size}行日志到剪贴板", Toast.LENGTH_SHORT).show()
    }

    override fun onDestroy() {
        super.onDestroy()
        hideLogWindow()
        floatingButton?.let { windowManager?.removeView(it) }
        windowManager?.removeView(logView)
    }
} 